package main

import (
	"bufio"
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"net/url"
	"os"
	"strings"
)

func readBody(response *http.Response) []byte {
	reader := bufio.NewReader(response.Body)
	var res []byte
	for {
		temp := make([]byte, 100)
		_, err := reader.Read(temp)
		if err == io.EOF {
			break
		}
		res = append(res, temp...)
	}
	return res
}

func postForm() {
	params := make(url.Values)
	params.Add("name", "hedaodao")
	params.Add("age", "18")

	response, err := http.Post("http://httpbin.org/post", "application/x-www-form-urlencoded", strings.NewReader(params.Encode()))
	if err != nil {
		fmt.Printf("请求失败，err-->%v", err)
		return
	}
	res := readBody(response)
	fmt.Println(string(res))
}

func postJSON() {
	stu := struct {
		Name string
		Age  int
	}{
		Name: "hedaodao",
		Age:  18,
	}
	bytes, err := json.Marshal(stu)
	if err != nil {
		fmt.Printf("序列化错误，err-->%v", err)
		return
	}
	response, err := http.Post("http://httpbin.org/post", "application/json", strings.NewReader(string(bytes)))
	res := readBody(response)
	fmt.Println(string(res))
}

func postFormData() {
	//1、构造一个缓冲区（所有的信息都是写入这里面）
	body := &bytes.Buffer{} //body实现了io.Reader、io.Writer
	writer := multipart.NewWriter(body)

	//提交的FormData是key-value形式的。value可以是字符串也可以是文件
	//2、写入数据：value为字符串。key为word，value为123
	writer.WriteField("word", "123")

	//3、写入数据：value为文件。key为uploadFile1，value为要上传的文件名
	uploadWriter, err := writer.CreateFormFile("uploadFile1", "avatar") //uploadWriter实现了io.Writer
	if err != nil {
		fmt.Printf("创建uploadWriter失败，err-->%v", err)
		return
	}
	file, err := os.Open("../download/avatar.png")
	if err != nil {
		fmt.Printf("打开文件失败，err-->%v", err)
		return
	}

	io.Copy(uploadWriter, file) //相当于把打开的文件，写入了uploadWriter

	//4、写完数据，一定要记得关闭writer。否则无法发送数据
	writer.Close()

	//fmt.Printf("%v\n", body.String()) //bytes.Buffer需要使用String方法才能转换为string类型

	//5、发起请求
	//fmt.Println(writer.FormDataContentType()) writer.FormDataContentType()是FormData的类型
	response, err := http.Post("http://httpbin.org/post", writer.FormDataContentType(), body)
	if err != nil {
		fmt.Printf("post请求失败，err-->%v", err)
		return
	}
	defer func() {
		response.Body.Close()
		file.Close()
	}()
	res := readBody(response)
	fmt.Println(string(res))

}

func main() {
	//postForm()
	//postJSON()
	postFormData()
}
